/*
 * SPDX-License-Identifier: BSD-2-Clause
 *
 * Copyright (C) 2017 Andes Technology Corporation
 * Copyright, 2024 Shandong Exponent Semiconductor CO., Ltd.            
 * Copyright, 2024 Sansec Technology CO., Ltd.                          
 *                     All Rights Reserved   
 *
 */

#ifndef _DCFRV_H_
#define _DCFRV_H_

#define EVALSOC_HART_COUNT_MAX    8

/*
 * DCF RV machine mode CSRs
 */

/* Configuration Registers */
#define CSR_DCF_MIMCFG         0xfc0
#define CSR_DCF_MDMCFG         0xfc1
#define CSR_DCF_MHINTCFG       0xfc2
#define CSR_DCF_MHINTCFG2      0xfc3
#define CSR_DCF_MVECCFG        0xfc7

#define PPMA_EN (1UL << PPMA_SHIFT)
#define PPMA_SHIFT 30

/* Crash Debug CSRs */
#define CSR_MCRASH_STATESAVE    0xfc8
#define CSR_MSTATUS_CRASHSAVE   0xfc9

/* Memory CSRs */
#define CSR_DCF_MILMCFG         0x7c0
#define CSR_DCF_MDLMCFG         0x7c1
#define CSR_DCF_MECCODE         0x7c2
#define CSR_DCF_MNVEC           0x7c3
#define CSR_DCF_MCCTL           0x7ca
#define CSR_DCF_MCCTLBASE       0x7cb
#define CSR_DCF_MCCTLCMD        0x7cc
#define CSR_DCF_MCCTLDATA       0x7cd
#define CSR_DCF_MPPIB           0x7f0
#define CSR_DCF_MFIOB           0x7f1

/* Hardware Stack Protection & Recording */
#define CSR_DCF_MHSPCTL         0x7c6
#define CSR_DCF_MHSPBOUND       0x7c7
#define CSR_DCF_MHSPBASE        0x7c8

/* Trap related CSR */
#define CSR_DCF_MXSTATUS        0x7c4
#define CSR_DCF_MDCAUSE         0x7c9
#define CSR_DCF_MSLIDELEG       0x7d5
#define CSR_DCF_MSAVESTATUS     0x7d6
#define CSR_DCF_MSAVEEPC1       0x7d7
#define CSR_DCF_MSAVECAUSE1     0x7d8
#define CSR_DCF_MSAVEEPC2       0x7d9
#define CSR_DCF_MSAVECAUSE2     0x7da
#define CSR_DCF_MSAVEDCAUSE1    0x7db
#define CSR_DCF_MSAVEDCAUSE2    0x7dc

/* Control CSRs */
#define CSR_DCF_MPLCTL         0x7c5
#define CSR_DCF_MMISCCTL       0x7d0
#define CSR_DCF_MCLKCTL        0x7df

/* Counter related CSRs */
#define CSR_DCF_MCOUNTERWEN    0x7ce
#define CSR_DCF_MCOUNTERINTEN  0x7cf
#define CSR_DCF_MCOUNTERMASKM  0x7d1
#define CSR_DCF_MCOUNTERMASKS  0x7d2
#define CSR_DCF_MCOUNTERMASKU  0x7d3
#define CSR_DCF_MCOUNTEROVF    0x7d4

/* PMA registers*/
#define CSR_DCF_PMACFG0 0xbc0
#define CSR_DCF_PMACFG1 0xbc1
#define CSR_DCF_PMACFG2 0xbc2
#define CSR_DCF_PMACFG3 0xbc3
#define CSR_DCF_PMAADDR0 0xbd0
#define CSR_DCF_PMAADDR1 0xbd1
#define CSR_DCF_PMAADDR2 0xbd2
#define CSR_DCF_PMAADDR3 0xbd3
#define CSR_DCF_PMAADDR4 0xbd4
#define CSR_DCF_PMAADDR5 0xbd5
#define CSR_DCF_PMAADDR6 0xbd6
#define CSR_DCF_PMAADDR7 0xbd7
#define CSR_DCF_PMAADDR8 0xbd8
#define CSR_DCF_PMAADDR9 0xbd9
#define CSR_DCF_PMAADDR10 0xbda
#define CSR_DCF_PMAADDR11 0xbdb
#define CSR_DCF_PMAADDR12 0xbdc
#define CSR_DCF_PMAADDR13 0xbdd
#define CSR_DCF_PMAADDR14 0xbde
#define CSR_DCF_PMAADDR15 0xbdf

/*
 * DCF RV supervisor mode CSRs
 */

/* Supervisor Trap Related */
#define CSR_DCF_SLIE        0x9c4
#define CSR_DCF_SLIP        0x9c5
#define CSR_DCF_SDCAUSE     0x9c9

/* Supervisor Counter Related */
#define CSR_DCF_SCOUNTERINTEN   0x9cf
#define CSR_DCF_SCOUNTERMASKM   0x9d1
#define CSR_DCF_SCOUNTERMASKS   0x9d2
#define CSR_DCF_SCOUNTERMASKU   0x9d3
#define CSR_DCF_SCOUNTEROVF     0x9d4
#define CSR_DCF_SCOUNTINHIBIT   0x9e0
#define CSR_DCF_SHPMEVENT3      0x9e3
#define CSR_DCF_SHPMEVENT4      0x9e4
#define CSR_DCF_SHPMEVENT5      0x9e5
#define CSR_DCF_SHPMEVENT6      0x9e6

/* Supervisor Control */
#define CSR_DCF_SCCTLDATA       0x9cd
#define CSR_DCF_SMISCCTL        0x9d0

/*
 * DCF RV user mode CSRs
 */
#define CSR_DCF_UITB            0x800
#define CSR_DCF_UCODE           0x801
#define CSR_DCF_UDCAUSE         0x809
#define CSR_DCF_UCCTLBASE       0x80b
#define CSR_DCF_UCCTLCMD        0x80c
#define CSR_DCF_WFE             0x810
#define CSR_DCF_SLEEPVALUE      0x811
#define CSR_DCF_TXEVT           0x812
#define DCF_UMISCCTL		    0x813

/*
 * DCF RV CSR encoding
 */

#define CSR_DCF_MHINTCFG_PLC_MASK (1 << 4)
#define CSR_DCF_MHINTCFG_PMNDS_MASK (1 << 15)
#define CSR_DCF_MHINTCFG_PPMA_MASK (1 << 30)
#define CSR_DCF_MHINTCFG_L2C_MASK  (1UL << 46)
#define CSR_DCF_MHINTCFG2_L2C_MASK (1UL << 14)

/* Performance monitor */
#define MIP_PMOVI (1 << 18)

/* marchid microid */
#define CSR_MARCHID_MICROID 0xffff

/* DCF mmiscctl register*/
#define DCF_MMISCCTL_VEC_PLIC_OFFSET            1
#define DCF_MMISCCTL_RVCOMPM_OFFSET             2
#define DCF_MMISCCTL_BRPE_OFFSET                3
#define DCF_MMISCCTL_MSA_OR_UNA_OFFSET          6
#define DCF_MMISCCTL_NON_BLOCKING_OFFSET        8
#define DCF_MCCTL_L1I_PREFETCH_OFFSET       9
#define DCF_MCCTL_L1D_PREFETCH_OFFSET       10
#define DCF_MCCTL_DC_WMERGE_OFFSET_1       13
#define DCF_MCCTL_DC_WMERGE_OFFSET_2       14

#define DCF_MMISCCTL_VEC_PLIC_EN        (1UL << DCF_MMISCCTL_VEC_PLIC_OFFSET)
#define DCF_MMISCCTL_RVCOMPM_EN         (1UL << DCF_MMISCCTL_RVCOMPM_OFFSET)
#define DCF_MMISCCTL_BRPE_EN            (1UL << DCF_MMISCCTL_BRPE_OFFSET)
#define DCF_MMISCCTL_MSA_OR_UNA_EN      (1UL << DCF_MMISCCTL_MSA_OR_UNA_OFFSET)
#define DCF_MMISCCTL_NON_BLOCKING_EN    (1UL << DCF_MMISCCTL_NON_BLOCKING_OFFSET)
#define DCF_MCCTL_L1I_PREFETCH_EN   (1UL << DCF_MCCTL_L1I_PREFETCH_OFFSET)
#define DCF_MCCTL_L1D_PREFETCH_EN   (1UL << DCF_MCCTL_L1D_PREFETCH_OFFSET)
#define DCF_MCCTL_DC_WMERGE_1_EN   (1UL << DCF_MCCTL_DC_WMERGE_OFFSET_1)
#define DCF_MCCTL_DC_WMERGE_2_EN   (1UL << DCF_MCCTL_DC_WMERGE_OFFSET_2)

#define DCF_MMISCCTL_MASK  (DCF_MMISCCTL_VEC_PLIC_EN | DCF_MMISCCTL_RVCOMPM_EN \
	| DCF_MMISCCTL_BRPE_EN | DCF_MMISCCTL_MSA_OR_UNA_EN | DCF_MMISCCTL_NON_BLOCKING_EN)

/* DCF mcctl register */
#define DCF_MCCTL_IC_EN_OFFSET      0
#define DCF_MCCTL_DC_EN_OFFSET      1
#define DCF_MCCTL_IC_ECCEN_OFFSET   2
#define DCF_MCCTL_DC_ECCEN_OFFSET   4
#define DCF_MCCTL_IC_RWECC_OFFSET   6
#define DCF_MCCTL_DC_RWECC_OFFSET   7
#define DCF_MCCTL_CCTL_SUEN_OFFSET  8

/* DCF cctl command */
#define V5_UCCTL_L1D_WBINVAL_ALL 6
#define V5_UCCTL_L1D_WB_ALL 7

#define DCF_MCCTL_IC_EN     (1UL << DCF_MCCTL_IC_EN_OFFSET)
#define DCF_MCCTL_DC_EN     (1UL << DCF_MCCTL_DC_EN_OFFSET)
#define DCF_MCCTL_IC_RWECC  (1UL << DCF_MCCTL_IC_RWECC_OFFSET)
#define DCF_MCCTL_DC_RWECC  (1UL << DCF_MCCTL_DC_RWECC_OFFSET)
#define DCF_MCCTL_CCTL_SUEN (1UL << DCF_MCCTL_CCTL_SUEN_OFFSET)

#define DCF_MCCTL_MASK (DCF_MCCTL_IC_EN | DCF_MCCTL_DC_EN \
	| DCF_MCCTL_IC_RWECC | DCF_MCCTL_DC_RWECC \
	| DCF_MCCTL_CCTL_SUEN | DCF_MCCTL_L1I_PREFETCH_EN \
	| DCF_MCCTL_L1D_PREFETCH_EN | DCF_MCCTL_DC_WMERGE_1_EN \
	| DCF_MCCTL_DC_WMERGE_2_EN)

#define DCF_L2CCTL_OFFSET           0x8
#define DCF_L2CCTL_ENABLE_OFFSET    0
#define DCF_L2CCTL_IPFDPT_OFFSET    3
#define DCF_L2CCTL_DPFDPT_OFFSET    5
#define DCF_L2CCTL_TRAMOCTL_OFFSET  8
#define DCF_L2CCTL_TRAMICTL_OFFSET  10
#define DCF_L2CCTL_DRAMOCTL_OFFSET  11
#define DCF_L2CCTL_DRAMICTL_OFFSET  13

#define DCF_L2CCTL_ENABLE_MASK      (1UL << DCF_L2CCTL_ENABLE_OFFSET)
#define DCF_L2CCTL_IPFDPT_MASK      (3UL << DCF_L2CCTL_IPFDPT_OFFSET)
#define DCF_L2CCTL_DPFDPT_MASK      (3UL << DCF_L2CCTL_DPFDPT_OFFSET)
#define DCF_L2CCTL_TRAMOCTL_MASK    (3UL << DCF_L2CCTL_TRAMOCTL_OFFSET)
#define DCF_L2CCTL_TRAMICTL_MASK    (1UL << DCF_L2CCTL_TRAMICTL_OFFSET)
#define DCF_L2CCTL_DRAMOCTL_MASK    (3UL << DCF_L2CCTL_DRAMOCTL_OFFSET)
#define DCF_L2CCTL_DRAMICTL_MASK    (1UL << DCF_L2CCTL_DRAMICTL_OFFSET)

/* DCF mmiscctl register*/
#define DCF_MMISCCTL_VEC_PLIC_OFFSET            1
#define DCF_MMISCCTL_RVCOMPM_OFFSET             2
#define DCF_MMISCCTL_BRPE_OFFSET                3
#define DCF_MMISCCTL_MSA_OR_UNA_OFFSET          6
#define DCF_MMISCCTL_NON_BLOCKING_OFFSET        8

#define DCF_MMISCCTL_VEC_PLIC_EN        (1UL << DCF_MMISCCTL_VEC_PLIC_OFFSET)
#define DCF_MMISCCTL_RVCOMPM_EN         (1UL << DCF_MMISCCTL_RVCOMPM_OFFSET)
#define DCF_MMISCCTL_BRPE_EN            (1UL << DCF_MMISCCTL_BRPE_OFFSET)
#define DCF_MMISCCTL_MSA_OR_UNA_EN      (1UL << DCF_MMISCCTL_MSA_OR_UNA_OFFSET)
#define DCF_MMISCCTL_NON_BLOCKING_EN    (1UL << DCF_MMISCCTL_NON_BLOCKING_OFFSET)

#define DCF_MMISCCTL_MASK  (DCF_MMISCCTL_VEC_PLIC_EN | DCF_MMISCCTL_RVCOMPM_EN \
	| DCF_MMISCCTL_BRPE_EN | DCF_MMISCCTL_MSA_OR_UNA_EN | DCF_MMISCCTL_NON_BLOCKING_EN)

/* DCF mcctl register */
#define DCF_MCCTL_IC_EN_OFFSET      0
#define DCF_MCCTL_DC_EN_OFFSET      1
#define DCF_MCCTL_IC_ECCEN_OFFSET   2
#define DCF_MCCTL_DC_ECCEN_OFFSET   4
#define DCF_MCCTL_IC_RWECC_OFFSET   6
#define DCF_MCCTL_DC_RWECC_OFFSET   7
#define DCF_MCCTL_CCTL_SUEN_OFFSET  8
#define DCF_MCCTL_L1I_PREFETCH_OFFSET       9
#define DCF_MCCTL_L1D_PREFETCH_OFFSET       10
#define DCF_MCCTL_DC_WMERGE_OFFSET_1       13
#define DCF_MCCTL_DC_WMERGE_OFFSET_2       14
#define DCF_MCCTL_L2C_WMERGE_OFFSET_1      15
#define DCF_MCCTL_L2C_WMERGE_OFFSET_2      16

#define DCF_MCCTL_DC_COHEN_OFFSET     19
#define DCF_MCCTL_DC_COHSTA_OFFSET    20

/* DCF cctl command */
#define V5_UCCTL_L1D_VA_INVAL	0
#define V5_UCCTL_L1D_VA_WB	1
#define V5_UCCTL_L1D_VA_WBINVAL	2
#define V5_UCCTL_L1D_WBINVAL_ALL 6
#define V5_UCCTL_L1D_WB_ALL 7
#define V5_UCCTL_L1D_INVAL_ALL 23

#define DCF_MCCTL_IC_EN     (1UL << DCF_MCCTL_IC_EN_OFFSET)
#define DCF_MCCTL_DC_EN     (1UL << DCF_MCCTL_DC_EN_OFFSET)
#define DCF_MCCTL_IC_RWECC  (1UL << DCF_MCCTL_IC_RWECC_OFFSET)
#define DCF_MCCTL_DC_RWECC  (1UL << DCF_MCCTL_DC_RWECC_OFFSET)
#define DCF_MCCTL_CCTL_SUEN (1UL << DCF_MCCTL_CCTL_SUEN_OFFSET)
#define DCF_MCCTL_L1I_PREFETCH_EN   (1UL << DCF_MCCTL_L1I_PREFETCH_OFFSET)
#define DCF_MCCTL_L1D_PREFETCH_EN   (1UL << DCF_MCCTL_L1D_PREFETCH_OFFSET)
#define DCF_MCCTL_DC_WMERGE_1_EN   (1UL << DCF_MCCTL_DC_WMERGE_OFFSET_1)
#define DCF_MCCTL_DC_WMERGE_2_EN   (1UL << DCF_MCCTL_DC_WMERGE_OFFSET_2)
#define DCF_MCCTL_L2C_WMERGE_1_EN   (1UL << DCF_MCCTL_L2C_WMERGE_OFFSET_1)
#define DCF_MCCTL_L2C_WMERGE_2_EN   (1UL << DCF_MCCTL_L2C_WMERGE_OFFSET_2)
#define DCF_MCCTL_DC_COHEN_EN       (1UL << DCF_MCCTL_DC_COHEN_OFFSET)
#define DCF_MCCTL_DC_COHSTA_EN      (1UL << DCF_MCCTL_DC_COHSTA_OFFSET)

#define DCF_MCCTL_MASK (DCF_MCCTL_IC_EN | DCF_MCCTL_DC_EN \
	| DCF_MCCTL_IC_RWECC | DCF_MCCTL_DC_RWECC \
	| DCF_MCCTL_CCTL_SUEN | DCF_MCCTL_L1I_PREFETCH_EN \
	| DCF_MCCTL_L1D_PREFETCH_EN | DCF_MCCTL_DC_WMERGE_1_EN \
	| DCF_MCCTL_DC_WMERGE_2_EN)

#define DCF_L2CCFG_OFFSET			0x0
#define DCF_L2CCFG_SIZE_OFFSET		7
#define DCF_L2CCFG_ECC_OFFSET		16
#define DCF_L2CCFG_MAP_OFFSET		20
#define DCF_L2CCFG_VERSION_OFFSET	24

#define DCF_L2CCFG_SIZE_MASK		(0x7fUL << DCF_L2CCFG_SIZE_OFFSET)
#define DCF_L2CCFG_ECC_MASK			(0xfUL << DCF_L2CCFG_ECC_OFFSET)
#define DCF_L2CCFG_MAP_MASK			(1UL << DCF_L2CCFG_MAP_OFFSET)
#define DCF_L2CCFG_VERSION_MASK		(0xffUL << DCF_L2CCFG_VERSION_OFFSET)

#define DCF_L2CCTL_OFFSET           0x8
#define DCF_L2CCTL_ENABLE_OFFSET    0
#define DCF_L2CCTL_IPFDPT_OFFSET    3
#define DCF_L2CCTL_DPFDPT_OFFSET    5
#define DCF_L2CCTL_TRAMOCTL_OFFSET  8
#define DCF_L2CCTL_TRAMICTL_OFFSET  10
#define DCF_L2CCTL_DRAMOCTL_OFFSET  11
#define DCF_L2CCTL_DRAMICTL_OFFSET  13

#define DCF_L2CCTL_ENABLE_MASK      (1UL << DCF_L2CCTL_ENABLE_OFFSET)
#define DCF_L2CCTL_IPFDPT_MASK      (3UL << DCF_L2CCTL_IPFDPT_OFFSET)
#define DCF_L2CCTL_DPFDPT_MASK      (3UL << DCF_L2CCTL_DPFDPT_OFFSET)
#define DCF_L2CCTL_TRAMOCTL_MASK    (3UL << DCF_L2CCTL_TRAMOCTL_OFFSET)
#define DCF_L2CCTL_TRAMICTL_MASK    (1UL << DCF_L2CCTL_TRAMICTL_OFFSET)
#define DCF_L2CCTL_DRAMOCTL_MASK    (3UL << DCF_L2CCTL_DRAMOCTL_OFFSET)
#define DCF_L2CCTL_DRAMICTL_MASK    (1UL << DCF_L2CCTL_DRAMICTL_OFFSET)

#ifndef __ASSEMBLER__
/*
 //For dcfrm2 cpu the CPU_ID field of marchid csr is 0x2d20, 
 #define is_dcf(series)				\
 ({							\
 	char value = csr_read(CSR_MARCHID) & 0xff;	\
 	(series) == (value >> 4) * 10 + (value & 0x0f);	\
 })
*/

#define is_dcf(series)				\
({							\
	char value = csr_read(CSR_MARCHID) & 0xffff;	\
	(series) == (value);	\
})


#define dcf_hpm()					\
({							\
	(((csr_read(CSR_DCF_MHINTCFG) &			\
	   CSR_DCF_MHINTCFG_PMNDS_MASK)			\
	  && misa_extension('S')) ? true : false);	\
})

#define dcf_performancelevelcontrol()				\
({							\
	((csr_read(CSR_DCF_MHINTCFG) &			\
	  CSR_DCF_MHINTCFG_PLC_MASK) ? true : false);	\
})

#endif /* __ASSEMBLER__ */

#endif /* _DCFRV_H_ */
